/**
 * Shapes
 * @module shapes
 * {@link http://www.w3.org/TR/css-shapes-1/ Specification}
 *
 * This module requires the modules Borders and Transforms
 * @requires borders
 * @requires transforms
 * =====================================================================================================================
 */

/**
 * Arrow
 * {@link https://css-tricks.com/snippets/css/css-triangle/ CSS Tricks}
 *
 * @example
 * .arrow(@color: #db5252, @direction: bottom, @base: 12px, @height: 6px);
 */
.arrow(@base, @height, @color: black, @direction: top) {
    .arrow-height() when (@height = auto) {
        @height: @base * sin(60deg);
    }
    .arrow-height();

    .arrow-direction() when (@direction = top) {
        border-left: @base / 2 solid transparent;
        border-right: @base / 2 solid transparent;
        border-bottom: @height solid @color;
    }

    .arrow-direction() when (@direction = bottom) {
        border-left: @base / 2 solid transparent;
        border-right: @base / 2 solid transparent;
        border-top: @height solid @color;
    }

    .arrow-direction() when (@direction = left) {
        border-top: @base / 2 solid transparent;
        border-bottom: @base / 2 solid transparent;
        border-right: @height solid @color;
    }

    .arrow-direction() when (@direction = right) {
        border-top: @base / 2 solid transparent;
        border-bottom: @base / 2 solid transparent;
        border-left: @height solid @color;
    }

    width: 0;
    height: 0;
    .arrow-direction();
}

/**
 * Arrow <Direction>
 *
 * @example
 * .arrow-up(@base: 100px, @height: 100px, @color: gray);
 */
.arrow-up(@base, @height, @color: black) {
    .arrow(@base: @base, @height: @height, @color: @color, @direction: top);
}
.arrow-down(@base, @height, @color: black) {
    .arrow(@base: @base, @height: @height, @color: @color, @direction: bottom);
}
.arrow-left(@base, @height, @color: black) {
    .arrow(@base: @base, @height: @height, @color: @color, @direction: left);
}
.arrow-right(@base, @height, @color: black) {
    .arrow(@base: @base, @height: @height, @color: @color, @direction: right);
}

/**
 * Square
 *
 * @example
 * .square(@size: 100px, @color: tomato);
 */
.square(@size, @color: black) {
    .rectangle(@size, @size, @color);
}

/**
 * Rectangle
 *
 * @example
 * .rectangle(@width: 150px, @height: 100px, @color: lightblue);
 */
.rectangle(@width, @height, @color: black) {
    width: @width;
    height: @height;
    background-color: @color;
}

/**
 * Circle
 *
 * @example
 * .circle(@size: 100px, @color: lightgreen);
 */
.circle(@size, @color: black) {
    .square(@size, @color);
    .border-radius(@size / 2);
}

/**
 * Oval
 *
 * @example
 * .oval(@width: 150px, @height: 100px, @color: gold);
 */
.oval(@width, @height, @color: black) {
    .rectangle(@width, @height, @color);
    .border-radius(@width / 2 ~"/" @height / 2);
}

/**
 * Ring
 *
 * @example
 * .ring(@size: 100px, @thickness: 20px, @color: chocolate);
 */
.ring(@size, @thickness, @color: black) {
    width: @size - @thickness * 2;
    height: @size - @thickness * 2;
    border: @thickness solid @color;
    .border-radius(@size / 2);
}

/**
 * Triangle
 *
 * @example
 * .triangle(@base: 100px, @height: 100px, @color: lightseagreen);
 */
.triangle(@base, @height, @color: black, @direction: top) {
    .triangle-height() when (@height = auto) {
        @height: @base * sin(60deg);
    }
    .triangle-height();

    .triangle-size() when (@direction = top), (@direction = bottom) {
        @triangle-width: @base;
        @triangle-height: @height;
    }
    .triangle-size() when (@direction = left), (@direction = right) {
        @triangle-width: @height;
        @triangle-height: @base;
    }
    .triangle-size();

    .rhombus-size() when (@direction = top), (@direction = bottom) {
        @rhombus-width: @base;
        @rhombus-height: @height * 2;
    }
    .rhombus-size() when (@direction = left), (@direction = right) {
        @rhombus-width: @height * 2;
        @rhombus-height: @base;
    }
    .rhombus-size();

    .rhombus-position() when (default()) {
        @rhombus-position: left top;
    }
    .rhombus-position() when (@direction = bottom) {
        @rhombus-position: left bottom;
    }
    .rhombus-position() when (@direction = right) {
        @rhombus-position: right top;
    }
    .rhombus-position();

    .rhombus(
        @width: @rhombus-width,
        @height: @rhombus-height,
        @color: @color,
        @position: @rhombus-position,
        @clip-width: @triangle-width,
        @clip-height: @triangle-height
    );

    overflow: hidden;
}

/**
 * Triangle <Direction>
 *
 * @example
 * .triangle-down(@base: 100px, @height: 100px, @color: lightseagreen);
 */
.triangle-up(@base, @height, @color: black) {
    .triangle(@base: @base, @height: @height, @color: @color, @direction: top);
}
.triangle-down(@base, @height, @color: black) {
    .triangle(@base: @base, @height: @height, @color: @color, @direction: bottom);
}
.triangle-left(@base, @height, @color: black) {
    .triangle(@base: @base, @height: @height, @color: @color, @direction: left);
}
.triangle-right(@base, @height, @color: black) {
    .triangle(@base: @base, @height: @height, @color: @color, @direction: right);
}

/**
 * Rhombus
 *
 * @example
 * .rhombus(@width: 150px, @height: 100px, @color: lightpink);
 */
.rhombus(@width, @height, @color: black, @position: left top, @clip-width: @width, @clip-height: @height) {
    @side: sqrt(@width * @width / 4 + @height * @height / 4);
    @position-x: extract(@position, 1);
    @position-y: extract(@position, 2);

    .rhombus-transform() when (@width = @height) {
        @delta: @side;
        .transform(rotate(45deg));
    }

    .rhombus-transform() when (default()) {
        @angle: asin(@height / @side / 2);
        @skew: @angle - convert(45deg, rad);
        @delta: @side * cos(@skew);
        .transform(rotate(45deg) skew(@skew, @skew));
    }

    width: @clip-width;
    height: @clip-height;
    position: relative;

    &:before {
        content: "";
        position: absolute;
        .rhombus-transform();
        @{position-x}: (@width - @delta) / 2;
        @{position-y}: (@height - @delta) / 2;
        width: @delta;
        height: @delta;
        background-color: @color;
    }
}

/**
 * Cross
 *
 * @example
 * .cross(@size: 100px, @thickness: 20px, @color: silver);
 */
.cross(@size, @thickness, @color: black) {
    position: relative;
    width: @size;
    height: @size;

    &:before {
        content: "";
        position: absolute;
        .rectangle(@size, @thickness, @color);
        margin: (@size - @thickness) / 2 0;
    }

    &:after {
        content: "";
        position: absolute;
        .rectangle(@thickness, @size, @color);
        margin: 0 (@size - @thickness) / 2;
    }
}

/**
 * Heart
 * {@link https://en.wikipedia.org/wiki/Square Wikipedia}
 *
 * @example
 * .heart(@width: auto, @height: 100px, @color: lightcoral);
 */
.heart(@width, @height, @color: black) {
    @angle: 45deg;

    .heart-size() when (@width = auto) {
        @width: (@height - @height * cos(@angle)) * 4;
    }
    .heart-size() when (@height = auto) {
        @height: (@width / 4 * sqrt(2) + @width / 4) / sin(@angle);
    }
    .heart-size();

    position: relative;
    width: @width;
    height: @height;

    @half-width: @width / 2;
    @inradius: @half-width / 2;
    @circumradius: @inradius * sqrt(2);
    @half-height: (@circumradius + @inradius) / sin(@angle);

    &:before,
    &:after {
        content: "";
        position: absolute;
        .rectangle(@half-width, @half-height, @color);
        .border-radius(@inradius @inradius 0 0);
        .transform-origin(@inradius @inradius);
    }

    &:before {
        left: 0;
        .transform(rotate(-@angle));
    }

    &:after {
        right: 0;
        .transform(rotate(@angle));
    }
}

/**
 * Star
 * {@link https://en.wikipedia.org/wiki/Pentagon Wikipedia}
 *
 * @example
 * .star(@width: auto, @height: 100px, @color: orange);
 */
.star(@width, @height, @color: black) {
    @angle: 36deg;

    .star-size() when (@width = auto) {
        @width: @height / cos(@angle / 2);
    }
    .star-size() when (@height = auto) {
        @height: @width * cos(@angle / 2);
    }
    .star-size();

    width: @width;
    height: @height;
    position: relative;

    @diagonal: @width;
    @side: @diagonal * sin(@angle / 2) * 2;
    @apex-height: @side * sin(@angle);

    &:before,
    &:after {
        content: "";
        position: absolute;
    }

    &:before {
        left: 50%;
        .arrow-right(@diagonal, @apex-height, @color);
        .transform(rotate(@angle / 2));
        .transform-origin(left top);
    }

    &:after {
        right: 50%;
        .arrow-left(@diagonal, @apex-height, @color);
        .transform(rotate(-@angle / 2));
        .transform-origin(right top);
    }

    i {
        position: absolute;
        top: @apex-height;
        .arrow-down(@diagonal, @apex-height, @color);
    }
}